/*******************************************************************************
 * CopyRight (c) 2020 
 *
 * \file    print_ctrl.h
 * \brief   调试输出级别控制模块
 * \author  张 靖
 * \version 1.0.0
 * \date    2020-06-22
 *
 * -----------------------------------------------------------------------------
 * 文件修改历史：
 * <时间>       | <版本>    | <作者>    | <描述>
 * 2020-06-22   | v1.0.0    | 张 靖     | 创建文件
 * -----------------------------------------------------------------------------
 ******************************************************************************/

#ifndef _PRINT_CTRL__H
#define _PRINT_CTRL__H

#include <stdio.h>
#include "publicdef.h"

/*!
 * \brief 调试输出级别
 */
#define NONE_   0
#define ERROR   1
#define WARN_   2
#define INFO_   3
#define ENTRY   4
#define DEBUG   5
#define DTAIL   6

/*!
 * \brief   将变量名转成字符串的宏定义函数
 */
#define name2str(name) (#name)

/*!
 * \brief   必须定义PRINT_LEVEL宏定义，否则编译阶段就直接报错退出
 */
#ifndef PRINT_LEVEL
#   error MUST Define PRINT_LEVEL!
#endif

/*!
 * \brief 调试输出接口
 *
 * \param[in] tag       调试级别
 * \param[in] tagstr    调试级别字符串
 * \param[in] fmt, ...  printf的可变参数
 */
int pr(int tag, char *tagstr, char *fmt, ...);

/*!
 * \brief 调试信息加上级别、时间、文件名、函数名、文件行、换行信息
 *
 * \param[in] tag       调试级别
 * \param[in] tagstr    调试级别字符串
 * \param[in] filestr   文件名字符串
 * \param[in] funcstr   函数名字符串
 * \param[in] line      当前代码行数
 * \param[in] fmt, ...  printf的可变参数
 */
int pr_func(int tag, char *tagstr, char *filestr, const char *funcstr, int line, char *fmt, ...);

#define pr_err(...)     \
    pr_func(ERROR, name2str(ERROR), __FILE__, __func__, __LINE__, __VA_ARGS__)
#define pr_warn(...)    pr(WARN_, name2str(WARN_), __VA_ARGS__);
#define pr_info(...)    pr(INFO_, name2str(INFO_), __VA_ARGS__);
#define pr_entry(inout) \
    pr(ENTRY, name2str(ENTRY), "%s() %s", __func__, #inout);
#define pr_debug(...)   pr(DEBUG, name2str(DEBUG), __VA_ARGS__);
#define pr_detail(...)  pr(DTAIL, name2str(DTAIL), __VA_ARGS__);

/*!
 * \brief   带调试级别的打印输出宏函数
 */
#define pr_pure(tag, ...)    do {                                   \
            if (tag <= PRINT_LEVEL)                                 \
                printf(__VA_ARGS__);                                \
        } while(0);

#define pr_err_pure(fmt, ...)            pr_pure(ERROR, fmt, ##__VA_ARGS__);
#define pr_warn_pure(fmt, ...)           pr_pure(WARN_, fmt, ##__VA_ARGS__);
#define pr_info_pure(fmt, ...)           pr_pure(INFO_, fmt, ##__VA_ARGS__);
#define pr_debug_pure(fmt, ...)          pr_pure(DEBUG, fmt, ##__VA_ARGS__);
#define pr_detail_pure(fmt, ...)         pr_pure(DTAIL, fmt, ##__VA_ARGS__);

#endif /* _PRINT_CTRL__H */
